package ae.pcfc.etks.online.web.controller.user.general.finance;

/* $Id: PaymentAdviceServiceController 
 * Copyright (C) 2013, Trakhees
 *  
 *  History
 *
 * Date  			Author 					Remarks
 * -------------------------------------------------------------
 * March 17, 2013 	Srikanth Yadav 	        Created
 *
 */

import java.io.IOException;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.joda.time.Days;
import org.joda.time.DateTime;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.UnhandledException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.joda.time.Days;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.support.RequestContextUtils;

import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.fnp.exception.FNPException;
import ae.pcfc.etks.online.fnp.service.FNPService;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.controller.user.general.person.UserPersonController;
import ae.pcfc.etks.online.web.model.PaymentAdviceStatus;

/**
 * Controller that handles all {@link UserPersonController}-related requests,
 * i.e.: all requests for /user/general/finance/Payment
 * 
 * @author Srikanth Yadav
 */

@Controller
@RequestMapping(ViewPath.FINANCE_PAYMENT_SERVICE)
public class PaymentAdviceServiceController extends BaseController {

	private static Logger log = LoggerFactory
			.getLogger(PaymentAdviceServiceController.class);

	private FNPService fnpDelegate;

	@Resource(name = "fnpDelegate")
	public void setFnpDelegate(FNPService fnpDelegate) {
		this.fnpDelegate = fnpDelegate;
	}

	private ClientRegistrationDelegate clientRegistrationDelegate;

	@Resource(name = "clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}

	@RequestMapping(value = "/show.htm", method = RequestMethod.GET)
	public void show(
			@ModelAttribute(value = ConstantsAdmin.CLIENT_PAYMENT_ADVICE_MODEL_KEY) PaymentAdviceStatus paymentAdviceStatus,
			Model map) {
	}

	@ModelAttribute(ConstantsAdmin.EXPORT_OPTION_MODEL_KEY)
	public List<LabelVO> populateExportOption() {

		List<LabelVO> labelList = new ArrayList<LabelVO>();
		LabelVO labelVO = new LabelVO();
		labelVO.setId("PDF");
		labelVO.setLabelAr("PDF");
		labelVO.setLabelEn("PDF");

		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId("XLSX");
		labelVO.setLabelAr("EXCEL");
		labelVO.setLabelEn("EXCEL");

		labelList.add(labelVO);

		return labelList;
	}

	@ModelAttribute(ConstantsAdmin.PAYMENT_ADVICE_STATUS_OPTION_MODEL_KEY)
	public List<LabelVO> populateStatusOption() {

		List<LabelVO> labelList = new ArrayList<LabelVO>();
		LabelVO labelVO = new LabelVO();
		labelVO.setId("OPEN");
		labelVO.setLabelAr("OPEN");
		labelVO.setLabelEn("OPEN");

		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId("CLOSED");
		labelVO.setLabelAr("CLOSED");
		labelVO.setLabelEn("CLOSED");

		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId("CANCELLED");
		labelVO.setLabelAr("CANCELLED");
		labelVO.setLabelEn("CANCELLED");

		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId("BLOCKED");
		labelVO.setLabelAr("BLOCKED");
		labelVO.setLabelEn("BLOCKED");

		labelList.add(labelVO);

		return labelList;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/show.htm")
	public String show(
			HttpServletRequest request,
			HttpServletResponse response,
			SessionStatus status,
			HttpSession session,
			Model model,
			@ModelAttribute(value = ConstantsAdmin.CLIENT_PAYMENT_ADVICE_MODEL_KEY) PaymentAdviceStatus paymentAdviceStatus,
			BindingResult errors) {

		try {
			if (errors.hasErrors()) {
				return ViewUtils.getForward(ViewPath.FINANCE_PAYMENT_SERVICE,
						PageType.SHOW);
			}
			
			//Check if the selected period is less than or equal to 100 days
			int days = Days.daysBetween(new DateTime(paymentAdviceStatus.getStartDate()),new DateTime(paymentAdviceStatus.getEndDate())).getDays();
			if( days >=100 ){
			
				String[] messageArgs2 = new String[] { getMessageSource().getMessage("error.finance.maxDateRange100", null,
						RequestContextUtils.getLocale(request)) };
				errors.reject("error.finance.maxDateRange100", messageArgs2, null);

				return ViewUtils.getForward(ViewPath.FINANCE_PAYMENT_SERVICE, PageType.SHOW);

			}		
			

			Object principal = SecurityContextHolder.getContext()
					.getAuthentication().getPrincipal();
			String strUserName = null;

			if (principal instanceof UserDetails) {
				strUserName = ((UserDetails) principal).getUsername();
			} else {
				strUserName = principal.toString();
			}

			String trakheesId = null;
			if (strUserName != null)
				trakheesId = this.clientRegistrationDelegate
						.findTrakheesIdByUserName(strUserName);

			if (trakheesId == null || trakheesId.isEmpty()) {

				String[] messageArgs = new String[] { getMessageSource()
						.getMessage("error.client.detail.not.found", null,
								RequestContextUtils.getLocale(request)) };
				log.debug("Trakhees Id not found agains the user");
				errors.reject("error.client.detail.not.found", messageArgs,
						null);

				return ViewUtils.getForward(ViewPath.FINANCE_PAYMENT_SERVICE,
						PageType.SHOW);

			}
			Byte[] bytes = this.fnpDelegate.paymentAdviceStatusReport(
					paymentAdviceStatus.getStartDate(),
					paymentAdviceStatus.getEndDate(),
					paymentAdviceStatus.getStatus(), trakheesId,
					ConstantsAdmin.SYSTEM_NAME_ONLINE_ADMIN, paymentAdviceStatus.getExportOption());

			response.setContentType("application/"+paymentAdviceStatus.getExportOption().toLowerCase());
			response.getOutputStream().write(ArrayUtils.toPrimitive(bytes));
			response.setHeader("Content-Disposition","attachment;filename=PaymentAdviceStatusReport."+ paymentAdviceStatus.getExportOption().toLowerCase());

			return ViewUtils.DEFAULT_VIEW;

		} catch (ConnectException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.client.detail.not.found", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (FNPException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.client.detail.not.found", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.client.detail.not.found", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			throw new UnhandledException(e.getMessage(), e.getCause());
		}

		return ViewUtils.getForward(ViewPath.FINANCE_PAYMENT_SERVICE,
				PageType.SHOW);
	}
}
